import re
import json
import requests
import subprocess
import os

def extract_best_quality_urls(html_content: str) -> tuple:
    # 使用正则表达式匹配 window.__playinfo__ 中的 JSON 字符串
    match = re.search(r'<script>window.__playinfo__\s*=\s*(\{(.*?\}))</script>', html_content)
    if not match:
        raise ValueError("未在HTML内容中找到'window.__playinfo__'对象。")

    # 提取并解析 JSON 数据
    playinfo_json = match.group(1)
    playinfo_data = json.loads(playinfo_json)

    if 'data' not in playinfo_data or 'dash' not in playinfo_data['data']:
        raise ValueError("JSON数据结构不正确，未找到'dash'字段。")

    dash_data = playinfo_data['data']['dash']

    # 获取最高画质视频链接（按照id降序排列，通常id越高画质越好）
    videos = sorted(dash_data.get('video', []), key=lambda x: x.get('id', 0), reverse=True)
    best_video_url = videos[0]['baseUrl'] if videos else None

    # 获取最高音质音频链接（按照带宽bw降序排列）
    audios = sorted(dash_data.get('audio', []), key=lambda x: x.get('bandwidth', 0), reverse=True)
    best_audio_url = audios[0]['baseUrl'] if audios else None
    
    return best_video_url, best_audio_url

def download_and_merge_stream(video_url: str, audio_url: str, output_filename: str):
    """
    下载视频和音频流，并使用 FFmpeg 将它们合并。
    """
    video_temp_file = "temp_video.m4s"
    audio_temp_file = "temp_audio.m4s"
    
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows; U; Windows NT 5.2) AppleWebKit/538.2.2 (KHTML, like Gecko) Chrome/18.0.860.0 Safari/538.2.2',
        'Referer': 'https://www.bilibili.com/'
    }
    
    try:
        print("开始下载视频流...")
        with requests.get(video_url, headers=headers, stream=True) as r:
            r.raise_for_status()
            with open(video_temp_file, "wb") as f:
                for chunk in r.iter_content(chunk_size=8192):
                    f.write(chunk)
        print("视频流下载完成。")

        print("开始下载音频流...")
        with requests.get(audio_url, headers=headers, stream=True) as r:
            r.raise_for_status()
            with open(audio_temp_file, "wb") as f:
                for chunk in r.iter_content(chunk_size=8192):
                    f.write(chunk)
        print("音频流下载完成。")

        print("开始合并视频和音频...")
        command = [
            "ffmpeg",
            "-i", video_temp_file,
            "-i", audio_temp_file,
            "-c", "copy",
            "-y",
            output_filename
        ]
        
        subprocess.run(command, check=True)
        print(f"视频已成功保存为：{output_filename}")
        
    except FileNotFoundError:
        print("错误：FFmpeg 未找到，请确保已安装并配置好环境变量。")
    except subprocess.CalledProcessError as e:
        print(f"错误：FFmpeg 合并失败: {e}")
    except requests.exceptions.RequestException as e:
        print(f"错误：下载文件失败，请检查链接是否有效: {e}")
    finally:
        if os.path.exists(video_temp_file):
            os.remove(video_temp_file)
        if os.path.exists(audio_temp_file):
            os.remove(audio_temp_file)
        print("临时文件已清理。")

# --- 主程序部分 ---
if __name__ == "__main__":
    # 将你提供的HTML内容粘贴到这里，用三引号包裹
    headers = {
   'User-Agent': 'Mozilla/5.0 (Windows; U; Windows NT 5.2) AppleWebKit/538.2.2 (KHTML, like Gecko) Chrome/18.0.860.0 Safari/538.2.2',
   'Referer': 'https://www.bilibili.com/',
   'Cookie': 'buvid3=CA599941-D69D-CCB7-59E3-C1836427B92178879infoc; b_nut=1757597078; _uuid=B10CDE575-1519-C797-7D37-C1364B10C57A879699infoc; buvid_fp=2102066ef044ba3ba97c90785e08b7d0; enable_web_push=DISABLE; buvid4=12BD04E2-1593-23C7-F0ED-7879AF8A02CD80519-025091121-hP4YsS2wj7oC0uRENNpNkg%3D%3D; SESSDATA=e776b7dc%2C1773149293%2C23c0b%2A92CjBilMZQvAfJw_vHFAe59v4EwAvAIG60ztHlbE678pdCbHEcDHKvT9av4SK-aaAR2BYSVnhGUmduelBUWi05aHdKRVVfVGxYU1VfZVV3d0ZLQ1U4WDJoYl9nUWx2T0h1LVNvZ0dpZXEzanlMNEdTVkpqYnpucnBPbGF4OTNPVlNQLXJOQzdHMHdnIIEC; bili_jct=ededceaaf35213628c8d36c6ea4e2b1c; DedeUserID=214438039; DedeUserID__ckMd5=2ecf106214ccb391; theme-tip-show=SHOWED; rpdid=0zbfAHZlcT|wcovKrxm|1J|3w1UX2cF; theme-avatar-tip-show=SHOWED; CURRENT_QUALITY=80; home_feed_column=5; hit-dyn-v2=1; bp_t_offset_214438039=1113545261616988160; bili_ticket=eyJhbGciOiJIUzI1NiIsImtpZCI6InMwMyIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NTgzNjUwNjYsImlhdCI6MTc1ODEwNTgwNiwicGx0IjotMX0.aMA6M55-6X1pqQg6fyxDvWX4nUbw2bb5NKsuDdOBf18; bili_ticket_expires=1758365006; b_lsid=7F2102E3D_19957844131; browser_resolution=1460-880; bmg_af_switch=1; bmg_src_def_domain=i1.hdslb.com; CURRENT_FNVAL=4048; sid=6v8vuof9'
    }
    
    url=input("请输入B站视频链接：")
    html_doc = requests.get(url,headers=headers).text
    with open("bilibili_video.html", "w", encoding="utf-8") as f:
        f.write(html_doc)
    try:
        # 1. 从HTML中提取链接
        video_link, audio_link = extract_best_quality_urls(html_doc)

        if video_link and audio_link:
            print("已提取视频和音频链接:")
            print(f"视频链接: {video_link}")
            print(f"音频链接: {audio_link}")
            
            # 2. 下载并合并视频
            download_and_merge_stream(video_link, audio_link, "bilibili_video.mp4")
        else:
            print("未能成功提取视频或音频链接。")
            
    except Exception as e:
        print(f"发生错误: {e}")